﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SAKS.Models;
using SAKS.ViewModels;
using SAKS.IServices;
using NHibernate;
using NHibernate.Linq;
using NHibernate.Criterion;
using AutoMapper;
using SAKS.Services.Query;


namespace SAKS.Services
{
    public class ProjectServices : IProjectServices 
    {
        public NHibernate.ISession Session { get; set; }

        public  bool IsUserInProject(string UserName,Guid projectid)
        {
            var query = (from p in Session.Query<Project>()
                        where p.Id == projectid && p.Users.Any(u => u.UserName == UserName)
                        select p).Count();
            return query == 1;
        }

        public Project GetProjectById(Guid projectid)
        {
            return Session.Get<Project>(projectid);
        }

        public void UpdateProjectInfo(ProjectCreateUpdateModel model)
        {
            var project = Session.QueryOver<Project>().Where(p => p.Id == model.Id).SingleOrDefault();
            project.EndDate = DateTime.Parse(model.EndDate);
            project.Members.Clear();
            var members = model.Members.Split(',');
            foreach (var item in members)
            {
                project.Members.Add(item);
            }
            project.Name = model.Name;
            project.Organizations.Clear();
            if(model.Organizations != null){
                var strs = model.Organizations.Split(',');
                foreach (var item in strs)
                {
                    project.Organizations.Add(item);
                }
            }
            project.PrimaryDesigner = model.PrimaryDesigner;
            project.ProjectLevel = model.ProjectLevel;
            project.ResponsibleOfficer = model.ResponsibleOfficer;
            project.SerialNumber = model.SerialNumber;
            project.SpecializedField = model.SpecializedField;
            project.StartDate = DateTime.Parse(model.StartDate);
            project.Summary = model.Summary;
            Session.Update(project);
        }

        public bool IsUserAdminOfProject(string username,Guid projectId)
        {
            var query = (from p in Session.Query<Project>()
                        where p.Id == projectId && p.Administrator.UserName == username
                        select p).Count();
            return query == 1;
        }

        public string GetAdminName(Guid projectId)
        {
            var query = from p in Session.Query<Project>()
                        where p.Id == projectId
                        select p.Administrator.UserName;
            return query.SingleOrDefault<string>();
        }

        public void AddMember(string username,Guid projectid)
        {
            var user = Session.QueryOver<User>().Where(u => u.UserName == username).SingleOrDefault();
            var project = Session.Get<Project>(projectid);
            user.Projects.Add(project);
            Session.Update(user);
        }

        public string GetProjectNameById(Guid projectId)
        {
            var query = from p in Session.QueryOver<Project>()
                        where p.Id == projectId
                        select p.Name;
            return query.SingleOrDefault<string>();
        }

        public void ReAppointAdmin(string username,Guid projectId)
        {
            var user = Session.QueryOver<User>().Where(u => u.UserName == username).SingleOrDefault();
            if (user == null)
                throw new ArgumentException("用户 " + username + " 不存在");
            var project = Session.Get<Project>(projectId);
            project.Administrator = user;
            Session.Update(project);
        }

        public List<User> GetMembers(Guid projectId)
        {
            return Session.Get<Project>(projectId).Users.ToList();
        }

        public void RemoveMember(string username,Guid projectId)
        {
            var user = Session.QueryOver<User>().Where(u => u.UserName == username).SingleOrDefault();
            if (user == null)
                throw new ArgumentException("用户 " + username + " 不存在");
            var project = Session.Get<Project>(projectId);
            project.Users.Remove(user);
            user.Projects.Remove(project);
            Session.Update(project);
        }

        public CreateStatus Create(Project project, string adminName)
        {
            var user = Session.QueryOver<User>().Where(u => u.UserName == adminName).SingleOrDefault();
            if (user == null)
                throw new ArgumentException("用户 " + adminName + " 不存在");

            user.Projects.Add(project);
            project.Administrator = user;
            project.Users = new List<User>();
            project.Users.Add(user);
            Session.Save(project);

            return CreateStatus.Succeed;
        }
        public void AddJoinRequest(Guid id,ProjectJoinRequest request)
        {
            var project = Session.QueryOver<Project>()
                .Where(p => p.Id == id)
                .JoinQueryOver<ProjectJoinRequest>(p => p.JoinRequests)
                .Where(j => j.UserName == request.UserName).SingleOrDefault();
            if (project != null)
            {
                if (project.JoinRequests.Count > 0)
                {
                    project.JoinRequests.Remove(project.JoinRequests.First());
                    Session.Update(project);
                }
            }
            else
            {
                project = Session.QueryOver<Project>().Where(p => p.Id == id).SingleOrDefault();
            }
            request.Project = project;
            project.JoinRequests.Add(request);
            Session.Save(request);
        }
        public void RemoveJoinRequest(Guid id)
        {
            var request = Session.Get<ProjectJoinRequest>(id);
            Session.Delete(request);
        }

        public object[] GetProjectJoinRequets(Guid id)
        {
            var requests = Session.QueryOver<Project>().Where(p => p.Id == id).SingleOrDefault().JoinRequests;
            var ret = from r in requests
                      select new
                      {
                          Id = r.Id,
                          UserName = r.UserName,
                          Message = r.Message
                      };
            return ret.ToArray();
        }
        public object[] List(int first, int pageSize, out int? totalRecords,string namesearch)
        {
            PagedProjectBriefSearch search = new PagedProjectBriefSearch(Session);
            search.Name = namesearch;
            search.First = first;
            search.PageSize = pageSize;
            search.Sort = SortColumn.CreatedDateDesc;
            var result = search.Execute();
            totalRecords = result.TotalItems;
            return (from p in result.PageOfResults
                   select new string[]{
                        p.Id.ToString(),
                        p.Name,
                        p.SpecializedField,
                        p.PrimaryDesigner,
                        p.ResponsibleOfficer,
                        p.CreatedDate.ToString("yyyy-MM-dd")
                   }).ToArray();
        }

        public IEnumerable<ProjectProcess> GetProcess(Guid projectId)
        {
            var project = Session.Get<Project>(projectId);
            if (project != null)
                return project.ProjectProcesses;
            else
                return null;
        }
        public void AddProcess(Guid projectId, ProjectProcess process)
        {
            var project = Session.Get<Project>(projectId);
            if (project != null)
            {
                process.CreatedDate = DateTime.Now;
                process.Project = project;
                project.ProjectProcesses.Add(process);
                Session.Update(project);
            }
           
        }
        public void RemoveProcess(Guid projectId, Guid processId)
        {
            var project = Session.Get<Project>(projectId);
            if (project != null)
            {
                var process = Session.Get<ProjectProcess>(processId);
                project.ProjectProcesses.Remove(process);
                Session.Update(project);
            }
        }

        public ProjectProcess GetNewestProcess(Guid projectId)
        {
            var query = Session.QueryOver<ProjectProcess>()
                .Where(p => p.Project.Id == projectId)
                .OrderBy(p => p.CreatedDate).Desc.Take(1);
            return query.SingleOrDefault();
        }

        public void ApproveProcess(Guid projectId,Guid ProcessId)
        {
            var process = Session.Get<ProjectProcess>(ProcessId);
            process.IsPassed = true;
            process.CheckDate = DateTime.Now;
            Session.Update(process);
        }

    }


}
